#ifndef LUTCOLORHSL16D88_H
#define LUTCOLORHSL16D88_H

#include <liblut/core/LutColor.h>
#include<boost/gil/typedefs.hpp>
#include<boost/gil/extension/toolbox/hsl.hpp>

using namespace boost;
using namespace gil;

namespace boost { namespace gil {
struct hsl16d88_pixel_t;
} }



namespace boost { namespace gil {

//define a scoped channel for value defining on degree from 0 to 360
//use by some application for hue value on hsv and hsl colorspace.
 struct bits16_zero { static bits16 apply() { return 0; } };
 struct bits16_360  { static bits16 apply() { return 360; } };
 typedef scoped_channel_value<bits16,bits16_zero,bits16_360> bits16d;
//--------------------


 //---- kth_element_type template specialization for hsl16duu
 template <>
 struct kth_element_type<hsl16d88_pixel_t, 0> {
     typedef bits16d type;
 };
 template <>
 struct kth_element_type<hsl16d88_pixel_t, 1> {
     typedef bits8 type;
 };
 template <>
 struct kth_element_type<hsl16d88_pixel_t, 2> {
     typedef bits8 type;
 };
 //---- kth_element_reference_type template specialization for hsl16duu
 template <>
 struct kth_element_reference_type<hsl16d88_pixel_t, 0> {
     typedef  channel_traits<bits16d>::reference type;
 };
 template <>
 struct kth_element_reference_type<hsl16d88_pixel_t, 1> {
     typedef  channel_traits<bits8>::reference type;
 };
 template <>
 struct kth_element_reference_type<hsl16d88_pixel_t, 2> {
     typedef  channel_traits<bits8>::reference type;
 };
 //---- kth_element_reference_type template specialization for const hsl16duu
 template <>
 struct kth_element_reference_type<const hsl16d88_pixel_t,0> {
     typedef  channel_traits<bits16d>::const_reference type;
 };
 template <>
 struct kth_element_reference_type<const hsl16d88_pixel_t,1> {
     typedef  channel_traits<bits8>::const_reference type;
 };
 template <>
 struct kth_element_reference_type<const hsl16d88_pixel_t,2> {
     typedef  channel_traits<bits8>::const_reference type;
 };
 //---- kth_element_const_reference_type template specialization for hsl16duu
 template <>
 struct kth_element_const_reference_type<hsl16d88_pixel_t, 0> {
     typedef  channel_traits<bits16d>::const_reference type;
 };
 template <>
 struct kth_element_const_reference_type<hsl16d88_pixel_t, 1> {
     typedef  channel_traits<bits8>::const_reference type;
 };
 template <>
 struct kth_element_const_reference_type<hsl16d88_pixel_t, 2> {
     typedef  channel_traits<bits8>::const_reference type;
 };

 struct hsl16d88_pixel_t {
   private:
      bits16d _v0;
      bits8 _v1, _v2;
   public:
      typedef hsl_layout_t layout_t;
      typedef  hsl16d88_pixel_t value_type;
      typedef value_type& reference;
      typedef const value_type& const_reference;
      BOOST_STATIC_CONSTANT(bool, is_mutable = true);


       kth_element_reference_type<value_type, 0>::type
               at(mpl::int_<0>) { return _v0; }
       kth_element_const_reference_type<value_type, 0>::type
               at(mpl::int_<0>) const { return _v0; }
       kth_element_reference_type<value_type, 1>::type
               at(mpl::int_<1>) { return _v1; }
       kth_element_const_reference_type<value_type, 1>::type
               at(mpl::int_<1>) const { return _v1; }
       kth_element_reference_type<value_type, 2>::type
               at(mpl::int_<2>) { return _v2; }
       kth_element_const_reference_type<value_type, 2>::type
               at(mpl::int_<2>) const { return _v2; }

      hsl16d88_pixel_t() {}
      hsl16d88_pixel_t(bits16d v0, bits8 v1, bits8 v2) : _v0(v0), _v1(v1), _v2(v2) {}
/*      hsl16d88_pixel_t& operator=(const value_type& p)
          {static_copy(p,*this); return *this;}

      // Construct from another compatible pixel type
      template <typename Pixel>
      hsl16d88_pixel_t(const Pixel& p,
                 typename enable_if_c<is_pixel<Pixel>::value>::type* dummy = 0)
          { check_compatible<Pixel>();}
*/
      template <typename P> hsl16d88_pixel_t& operator=(const P& p)
         {assign(p, mpl::bool_<is_pixel<P>::value>()); return *this; }
      template <typename P> bool   operator==(const P& p) const
         {return equal(p, mpl::bool_<is_pixel<P>::value>()); }
      template <typename P> bool   operator!=(const P& p) const
         {return !(*this==p); }



      template <typename hslCB > hsl16d88_pixel_t(const hslCB& c) :
            _v0(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,0>::value>(c)),
            _v1(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,1>::value>(c)),
            _v2(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,2>::value>(c)) {}

        // Support for l-value reference proxy copy construction
        template <typename hslCB > hsl16d88_pixel_t( hslCB& c) :
            _v0(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,0>::value>(c)),
            _v1(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,1>::value>(c)),
            _v2(gil::at_c<detail::mapping_transform<
                layout_t,typename hslCB::layout_t,2>::value>(c)) {}

  private:
      template <typename Pixel> void assign(const Pixel& p, mpl::true_)
        { check_compatible<Pixel>(); static_copy(p,*this); }
      template <typename Pixel> bool  equal(const Pixel& p, mpl::true_)
        const { check_compatible<Pixel>(); return static_equal(*this,p); }
      template <typename Pixel> void check_compatible() const
        {gil_function_requires<PixelsCompatibleConcept<Pixel,hsl16d88_pixel_t> >();}

 };


 template <int K> inline
 typename kth_element_reference_type<hsl16d88_pixel_t,K>::type
    at_c(hsl16d88_pixel_t& p) { return p.at(mpl::int_<K>()); }

 template <int K> inline
 typename kth_element_const_reference_type<hsl16d88_pixel_t,K>::type
    at_c(const hsl16d88_pixel_t& p) { return p.at(mpl::int_<K>()); }

 template <>
 struct color_space_type<hsl16d88_pixel_t> {
     typedef  hsl_layout_t::color_space_t type;
 };

 template <>
 struct channel_mapping_type<hsl16d88_pixel_t> {
     typedef  hsl_layout_t::channel_mapping_t type;
 };

 template <>
 struct is_planar<hsl16d88_pixel_t > : public mpl::false_ {};




} }

class LutColorHSL16d88 : public LutColorI
{
  public:
    LutColorHSL16d88();
    virtual ~LutColorHSL16d88();
    //get set
    void setValues(uint32_t C1, uint32_t C2, uint32_t C3);
    uint32_t getC1i() const;
    uint32_t getC2i() const;
    uint32_t getC3i() const;
    void setValues(float C1, float C2, float C3);
    float getC1f() const;
    float getC2f() const;
    float getC3f() const;

  private:
    boost::gil::hsl16d88_pixel_t m_color;
//    boost::gil::hsl32f_pixel_t m_color;
};



#endif // LUTCOLORHSL16D88_H
